#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define endl '\n'
const int N = 2e5 + 5;

map<int, set<int>> mp;   // key ->set
map<set<int>, int> key;  // set->key
int tot = 0;
int getkey(const set<int>& st) {
  if (!key.count(st)) {
    key[st] = ++tot;
    mp[tot] = st;
  }
  return key[st];
}
int add(int a, int b) {
  set<int> stb = mp[b];
  stb.insert(a);
  return getkey(stb);
}
int one(int a, int b) {
  set<int> sta = mp[a], stb = mp[b];
  if (sta.size() > stb.size()) swap(sta, stb);
  for (int x : sta) stb.insert(x);
  return getkey(stb);
}
int both(int a, int b) {
  set<int> sta = mp[a], stb = mp[b];
  set<int> stc;
  if (sta.size() > stb.size()) swap(sta, stb);
  for (int x : sta)
    if (stb.count(x)) stc.insert(x);
  return getkey(stc);
}
void solve() {
  stack<int> sst;
  int n;
  cin >> n;
  vector<string> cmds(n);
  rep(i, 0, n - 1) cin >> cmds[i];
  for (string cmd : cmds) {
    if (cmd == "PUSH") sst.push(getkey(set<int>{}));
    if (cmd == "DUP") sst.push(sst.top());
    if (cmd == "ADD" || cmd == "UNION" || cmd == "INTERSECT") {
      int a = sst.top();
      sst.pop();
      int b = sst.top();
      sst.pop();
      int c;
      if (cmd == "ADD") c = add(a, b);
      if (cmd == "UNION") c = one(a, b);
      if (cmd == "INTERSECT") c = both(a, b);
      sst.push(c);
    }
    cout << mp[sst.top()].size() << endl;
  }
  cout << "***" << endl;
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  // freopen("1.txt", "r", stdin);
  // freopen("2.txt", "w", stdout);
  int t;
  cin >> t;
  while (t--) solve();
  return 0;
}